Hi Dai Gei Ho~ 我是 Winnie ~
在今天文章中,我們要來繼續延伸 昨天文章的主題 Provide & Inject ,針對 響應式資料傳遞的操作 來做介紹。
由於 provide/inject 主要作用 是 跨元件之間資料狀態溝通 ,而其綁定的值預設並不是響應式的。所以 如果需要增加 provide/ inject 中的提供值的響應性,我們可以通過傳遞響應式資料來處理,例如在 provide 時 使用 ref() 或 reactive()把資料包裝起來 :
// App.vue
import { ref, reactive, provide }
export default{
setup (){
const name = ref('winnie');
const location = reactive({
city: '台北市',
area: '大安區'
}])
provide('name',name)
provide('location',location)
}
}
如上方範例,我們將 name
與 location
provide出去了,而 當這兩個 被更改,APP.vue中的值也會跟著更新。是不是超級方便的?但是...千萬別這麼做(話說,在前幾個月我也做過這事,而且還不只一次XD),這也是 官方文件中 建議 別這麼做的
因為 provide/inject 不像 Vuex 可以追蹤各個state的變動,如果資料狀態操作分散在多個子元件中,被更改出現問題時,要解決就會變得困難,同時程式碼也會變得很難維護。
因此,官方文件這邊就提出建議,當使用provide/inject 值時,盡可能將對 響應式property 的所有修改及操作,限制在 provide()的元件內部中,來更新 響應式的資料狀態。
有點抽象,先讓我們來看看 以下範例:
//provide.vue
import { ref, provide, readonly }
export default{
setup(){
const count = ref(0);
const setCount = ()={
count.vlaue++
}
provide('count', readonly(count)) // 使用readonly把保護起來,只能透過setCount來更動它。
provide('setCount',setCount)
}
}
//inject.vue
<template>
<div>{{count}}</div>
<button @click="updateCount">+1</button>
</template>
//略...
setup(){
const count =inject('count') //因為被 readonly保護了,所以只可讀,不可直接修改他
const updateCount = inject('setCount')
return{
count,
updateCount
}
}
//略...
從上計數器範例可以看到,當子元件 inject了 上層元件provide出來的state時,只能透過 provide 所提供的 修改函式來 更新其狀態。同時為確保傳遞出來的資料不會被子元件任意更改,在這邊可以使用 readonly 或者 computed 方法建立唯讀資料。
以上就是今天的文章,如任何有問題歡迎大家多多指教,謝謝大家。